/*
 * Copyright 2012 Jin Kwon <jinahya at gmail.com>.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package com.googlecode.w3c.widgets.configuration;


import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;


/**
 *
 * @author Jin Kwon <jinahya at gmail.com>
 */
public class FeatureWrapper extends AbstractWrapper<Feature> {


    /**
     * Creates a new instance.
     */
    public FeatureWrapper() {
        this(new Feature());
    }


    /**
     * Creates a new instance.
     *
     * @param feature the feature to be wrapped
     */
    public FeatureWrapper(final Feature feature) {
        super(feature);
    }


    /**
     * Returns the wrapped feature.
     *
     * @return feature
     */
    public Feature getFeature() {
        return wrappee;
    }


    /**
     * Returns params.
     *
     * @return params.
     */
    public Collection<Param> getParams() {

        return wrappee.getParam();
    }


    /**
     * Returns params as a map of
     * <code>@name</code>s and
     * <code>Param</code>s.
     *
     * @return params.
     */
    public Map<String, Param> getParamsMappedByNames() {

        final Map<String, Param> params = new LinkedHashMap<String, Param>();

        for (Param param : getParams()) {
            final String name = param.getName();
            if (!params.containsKey(name)) {
                params.put(name, param);
            }
        }

        return params;
    }


    /**
     * Replaces params.
     *
     * @param params new params
     */
    public void setParams(final Collection<Param> params) {

        if (params == null) {
            throw new NullPointerException("null params");
        }

        final Map<String, Param> mapped = new LinkedHashMap<String, Param>();

        for (Param param : params) {
            if (param == null) {
                throw new IllegalArgumentException("null param");
            }
            final String name = param.getName();
            if (name == null) {
                throw new IllegalArgumentException("null @name");
            }
            if (mapped.put(name, param) != null) {
                throw new IllegalArgumentException(
                    "duplicated param for @name(" + name + ")");
            }
        }

        setParams(mapped);
    }


    /**
     * Replaces params with given map of
     * <code>@name</code>s and
     * <code>Param</code>s.
     *
     * @param params new params
     */
    public void setParams(final Map<String, Param> params) {

        if (params == null) {
            throw new NullPointerException("null params");
        }

        for (Entry<String, Param> entry : params.entrySet()) {
            final String name = entry.getKey();
            if (name == null || name.trim().isEmpty()) {
                throw new IllegalArgumentException("null or empty @name");
            }
            final Param param = entry.getValue();
            if (param == null) {
                throw new IllegalArgumentException(
                    "null param for @name(" + name + ")");
            }
            if (!name.equals(param.getLang())) {
                throw new IllegalArgumentException(
                    "illegal mapping: @name(" + name + ") - param.@name("
                    + param.getName() + ")");
            }
        }

        getParams().clear();
        getParams().addAll(params.values());
    }


}

